#!/usr/bin/ruby
require "rubygems"
require "opengl"
require "glut"
require "m3g"
require "pp"


class MyGLUTWidget
  def initialize
    GLUT.Init
    GLUT.InitWindowSize 256, 256
    GLUT.InitDisplayMode GLUT::GLUT_DOUBLE | GLUT::GLUT_RGB | GLUT::GLUT_DEPTH
    GLUT.CreateWindow "Ruby-M3G"

    initialize_scene

    GLUT.ReshapeFunc  method(:reshape).to_proc()
    GLUT.DisplayFunc  method(:display).to_proc()
    GLUT.KeyboardFunc method(:keyboard).to_proc()
    GLUT.MouseFunc    method(:mouse).to_proc()
    GLUT.IdleFunc     method(:idle).to_proc()
  end

  def initialize_scene

    controller = M3G::AnimationController.new

    keyframe_trans1 = M3G::KeyframeSequence.new 3, 3, M3G::KeyframeSequence::LINEAR
    frame_trans1 = [[1,0,0], [0,0,0], [1,0,0]]
    keyframe_trans1.keyframe[0] = 0, frame_trans1[0]
    keyframe_trans1.keyframe[1] = 100, frame_trans1[1]
    keyframe_trans1.keyframe[2] = 200, frame_trans1[2]
    keyframe_trans1.repeat_mode = M3G::KeyframeSequence::LOOP
    keyframe_trans1.valid_range = 0, 2
    keyframe_trans1.duration    = 200

    keyframe_trans2 = M3G::KeyframeSequence.new 3, 3, M3G::KeyframeSequence::LINEAR
    frame_trans2 = [[-1,0,0], [0,0,0], [-1,0,0]]
    keyframe_trans2.keyframe[0] = 0, frame_trans2[0]
    keyframe_trans2.keyframe[1] = 100, frame_trans2[1]
    keyframe_trans2.keyframe[2] = 200, frame_trans2[2]
    keyframe_trans2.repeat_mode = M3G::KeyframeSequence::LOOP
    keyframe_trans2.valid_range = 0, 2
    keyframe_trans2.duration    = 200
    
    animation_trans1 = M3G::AnimationTrack.new keyframe_trans1, M3G::AnimationTrack::TRANSLATION
    animation_trans1.controller = controller

    animation_trans2 = M3G::AnimationTrack.new keyframe_trans2, M3G::AnimationTrack::TRANSLATION
    animation_trans2.controller = controller


    scale = 1
    bias  = [0,0,0]

    position_values1 = [1,-1,0, 1,1,0, -1,-1,0, -1,1,0]
    positions1       = M3G::VertexArray.new 4, 3, 2
    positions1.values[0,4] = position_values1

    vertices1 = M3G::VertexBuffer.new
    vertices1.positions = positions1, scale, bias

    position_values2 = [1,-1,-3, 1,1,-3, -1,-1,-3, -1,1,-3]
    positions2       = M3G::VertexArray.new 4, 3, 2
    positions2.values[0,4] = position_values2

    vertices2 = M3G::VertexBuffer.new
    vertices2.positions = positions2, scale, bias

    strips = [4]
    tris = M3G::TriangleStripArray.new 0, strips

    mat1 = M3G::Material.new
    mat1.color[M3G::Material::DIFFUSE] = 0x7f4c4cb2

    cmode1 = M3G::CompositingMode.new
    cmode1.blending = M3G::CompositingMode::ALPHA
    cmode1.depth_test_enable = false
    
    mat2 = M3G::Material.new
    mat2.color[M3G::Material::DIFFUSE] = 0x7f4cb2b2

    cmode2 = M3G::CompositingMode.new
    cmode2.blending = M3G::CompositingMode::ALPHA
    cmode2.depth_test_enable = false

    app1 = M3G::Appearance.new
    app1.material = mat1;
    app1.compositing_mode = cmode1

    app2 = M3G::Appearance.new
    app2.material = mat2;
    app2.compositing_mode = cmode2

    mesh1 = M3G::Mesh.new vertices1, tris, app1
    mesh1.animation_track << animation_trans1
    mesh1.translate 1,0,0

    mesh2 = M3G::Mesh.new vertices2, tris, app2
    mesh2.animation_track << animation_trans2
    mesh2.translate -1,0,0

    grp = M3G::Group.new
    grp.translate 0,0,-3
    grp.child << mesh1
    grp.child << mesh2

    cam = M3G::Camera.new
    cam.translate 0,0,5

    @wld = M3G::World.new
    @wld.active_camera = cam  
    @wld.child << cam
    @wld.child << grp

    @world_time = 0
  end

  def reshape width, height
    g3d = M3G::Graphics3D::instance
    g3d.viewport = 0,0,width,height
    @wld.active_camera.perspective = 45, width/(height*1.0), 0.1, 100
  end

  def display
    g3d = M3G::Graphics3D::instance
    g3d.render @wld
    GLUT.SwapBuffers()
  end
  
  def keyboard key, x, y
    if key == 113  # 'q'
      exit
    elsif key == 32 # ' '
      puts "main: time = #{@world_time}"
      @wld.animate @world_time
      @world_time += 5
    end
    GLUT.PostRedisplay
  end

  def mouse button, state, x, y
  end

  def idle
    GLUT.PostRedisplay
  end

  def start
    GLUT.MainLoop
  end

end


MyGLUTWidget.new.start

